package schema.ext;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

import javax.xml.bind.JAXBException;

import jhunter.common.exception.ConfigException;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;

import schema.Environment;
import schema.Node;
import schema.io.AppsXmlLoader;
import schema.vo.apps.App;
import schema.vo.apps.Apps;

public class AppsExt extends Node {

	private AppsXmlLoader appsXmlLoader = new AppsXmlLoader();

	private Apps apps;

	private FileAlterationMonitor fileMonitor;

	public AppsExt(String path) {
	
		load(path);
	}

	protected String getURL(String pp, String infoClass) {
		String fileName = "";
		if (Environment.isDev()) {
			URL url = getClassLoader().getResource("");
			String p = url.getFile() + pp;
			fileName = FilenameUtils.normalize(p);
		} else {
			int ind = pp.indexOf("classes");
			String p = pp.substring(ind + 7);
			// URL url = Class.forName(infoClass).getResource("../" + p);
			fileName = "../" + p;
			//TODO
		}

		System.out.println("find app config file : " + fileName);
		return fileName;
	}

	public void load(String path) {
		InputStream is = setFileAndReturnStream(path);
		try {
			apps = (Apps) appsXmlLoader.getUnmarshal().unmarshal(is);
			List<App> appList = apps.getApp();
			for (App app : appList) {
				AppExt appExt = new AppExt();
				appExt.setParent(this);
				String pp = app.getAppResource();
				appExt.load(getURL(pp, app.getInfoClass()));
				// this.getChildren().add(appExt);
				this.getChildren().put(appExt.getContextPath(), appExt);
			}
		} catch (JAXBException e) {
			System.out.println(path);
			e.printStackTrace();

			throw new ConfigException(e);
		}

		if (Environment.isDev() && fileMonitor == null) {
			fileMonitor = new FileAlterationMonitor(1000);
			File mFile = new File(getFile()).getParentFile();
			FileAlterationObserver observer = new FileAlterationObserver(mFile);
			observer.addListener(new FileAlterationListenerAdaptor() {
				@Override
				public void onFileChange(File file) {
					String path = file.getPath();
					if (path.equals(AppsExt.this.getFile())) {
						load(path);
					}
				}
			});
			fileMonitor.addObserver(observer);
			try {
				fileMonitor.start();
			} catch (Exception e) {
				e.printStackTrace();
				throw new ConfigException(e);
			}
		}
	}

	public Apps getApps() {
		return apps;
	}

	public void setApps(Apps apps) {
		this.apps = apps;
	}

	@Override
	protected ClassLoader getClassLoader() {
		return Environment.getDefaultClassLoader();
	}

}
